import { ShapeFlages } from '../shared/ShapeFlags'

export const Fragment = Symbol("Fragment");
export const Text = Symbol("Text");

/**
 * 创建一个 vnode
 * 
 * @param type 一个组件对象（object） 或者 Element值（string）
 * @param props props 数据
 * @param children 组件 or Element 的子元素
 * @returns 
 */
export function createVNode(type, props?, children?) {
    const vnode = {
        type,
        props,
        shapeFlag: getShapeFlag(type),
        children,
    }

    // 处理子节点 children，根据子节点类型，对 shapeFlag 进行赋值运算
    if (Array.isArray(children)) {
        // | 或位运算对 shapeFlage 进行+值
        vnode.shapeFlag = vnode.shapeFlag | ShapeFlages.ARRAY_CHILDREN; // 数组子节点
    } else if (typeof children == "string") {
        vnode.shapeFlag = vnode.shapeFlag | ShapeFlages.TEXT_CHILDREN; // 文本子节点
    }


    // 如果 vnode 是一个组件类型，并且 children 为一个 object ，代表该组件的子节点为插槽
    if (vnode.shapeFlag & ShapeFlages.STATEFUL_COMPONENT) {
        if (typeof vnode.children == "object"){
            vnode.shapeFlag = vnode.shapeFlag | ShapeFlages.SLOT_CHILDREN; // 插槽子节点
        }
    }

    // 返回一个 vnode 对象
    return vnode
}



/**
 * 创建一个纯文本虚拟节点
 * @returns 返回一个纯文本节点
 */
 export function createTextVNode(text: string) {
    let vnode = createVNode(Text, {}, text);
    // 返回一个 vnode 纯文本节点
    return vnode;
}



/**
 * 传入一个 vnode 的type 值， 返回对应的 ShapeFlage 代码
 * @param type vnode.type  值 
 * @returns ShapeFlage 代码
 */
export function getShapeFlag(type) {
    const flag = typeof type == "string" ? ShapeFlages.ELEMENT : ShapeFlages.STATEFUL_COMPONENT;
    return flag;
}

